﻿namespace DotRas
{
    using DotRas.Design;
    using pptpclient.Properties;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.IO;
    using System.Security.Permissions;
    using System.Threading;

    [ToolboxBitmap(typeof(RasPhoneBook), "DotRas.RasPhoneBook.bmp"), ToolboxItem(true), PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
    public sealed class RasPhoneBook : RasComponent
    {
        private bool _enableFileWatcher;
        private RasEntryCollection _entries;
        private string _path;
        private RasPhoneBookType _phoneBookType;
        private FileSystemWatcher _watcher;

        [DotRas.SRDescription("RPBChangedDesc"), DotRas.SRCategory("CatBehavior")]
        public event EventHandler<EventArgs> Changed;

        [DotRas.SRCategory("CatBehavior"), DotRas.SRDescription("RPBDeletedDesc")]
        public event EventHandler<EventArgs> Deleted;

        [DotRas.SRDescription("RPBRenamedDesc"), DotRas.SRCategory("CatBehavior")]
        public event EventHandler<RenamedEventArgs> Renamed;

        public RasPhoneBook()
        {
            this.InitializeComponent();
        }

        public RasPhoneBook(IContainer container) : base(container)
        {
            this.InitializeComponent();
        }

        private void _watcher_Changed(object sender, FileSystemEventArgs e)
        {
            this.Entries.Load();
            this.OnChanged(EventArgs.Empty);
        }

        private void _watcher_Deleted(object sender, FileSystemEventArgs e)
        {
            this.Entries.Load();
            this.OnDeleted(EventArgs.Empty);
        }

        private void _watcher_Renamed(object sender, RenamedEventArgs e)
        {
            if (e.ChangeType == WatcherChangeTypes.Renamed)
            {
                this.Path = e.FullPath;
                this._watcher.EnableRaisingEvents = false;
                this._watcher.Filter = e.Name;
                this._watcher.EnableRaisingEvents = this.EnableFileWatcher;
            }
            this.OnRenamed(e);
        }

        public static string GetPhoneBookPath(RasPhoneBookType phoneBookType)
        {
            string str = null;
            if (phoneBookType == RasPhoneBookType.Custom)
            {
                return str;
            }
            Environment.SpecialFolder commonApplicationData = Environment.SpecialFolder.CommonApplicationData;
            if (phoneBookType == RasPhoneBookType.User)
            {
                commonApplicationData = Environment.SpecialFolder.ApplicationData;
            }
            return System.IO.Path.Combine(Environment.GetFolderPath(commonApplicationData), @"Microsoft\Network\Connections\Pbk\rasphone.pbk");
        }

        protected override void InitializeComponent()
        {
            this._watcher = new FileSystemWatcher();
            this._watcher.BeginInit();
            this._watcher.Renamed += new RenamedEventHandler(this._watcher_Renamed);
            this._watcher.Deleted += new FileSystemEventHandler(this._watcher_Deleted);
            this._watcher.Changed += new FileSystemEventHandler(this._watcher_Changed);
            this._watcher.EndInit();
            base.InitializeComponent();
        }

        private void OnChanged(EventArgs e)
        {
            base.RaiseEvent<EventArgs>(this.Changed, e);
        }

        private void OnDeleted(EventArgs e)
        {
            base.RaiseEvent<EventArgs>(this.Deleted, e);
        }

        private void OnRenamed(RenamedEventArgs e)
        {
            base.RaiseEvent<RenamedEventArgs>(this.Renamed, e);
        }

        public void Open()
        {
            this.Open(false);
        }

        public void Open(bool openUserPhoneBook)
        {
            RasPhoneBookType allUsers = RasPhoneBookType.AllUsers;
            if (openUserPhoneBook)
            {
                allUsers = RasPhoneBookType.User;
            }
            this.Open(GetPhoneBookPath(allUsers));
            this.PhoneBookType = allUsers;
        }

        public void Open(string phoneBookPath)
        {
            if (string.IsNullOrEmpty(phoneBookPath))
            {
                DotRas.ThrowHelper.ThrowArgumentException("phoneBookPath", Resources.Argument_StringCannotBeNullOrEmpty);
            }
            FileInfo info = new FileInfo(phoneBookPath);
            if (string.IsNullOrEmpty(info.Name))
            {
                DotRas.ThrowHelper.ThrowArgumentException("phoneBookPath", Resources.Argument_InvalidFileName);
            }
            this.Path = phoneBookPath;
            this.PhoneBookType = RasPhoneBookType.Custom;
            this._watcher.Path = info.DirectoryName;
            this._watcher.Filter = info.Name;
            this._watcher.EnableRaisingEvents = this.EnableFileWatcher;
            if (info.Exists)
            {
                this.Entries.Load();
            }
        }

        [DotRas.SRDescription("RPBEnableFileWatcherDesc"), DefaultValue(false), DotRas.SRCategory("CatBehavior")]
        public bool EnableFileWatcher
        {
            get
            {
                return this._enableFileWatcher;
            }
            set
            {
                this._enableFileWatcher = value;
                if (!string.IsNullOrEmpty(this.Path))
                {
                    this._watcher.EnableRaisingEvents = value;
                }
            }
        }

        [Browsable(false)]
        public RasEntryCollection Entries
        {
            get
            {
                if (this._entries == null)
                {
                    this._entries = new RasEntryCollection(this);
                }
                return this._entries;
            }
        }

        [Browsable(false)]
        public string Path
        {
            get
            {
                return this._path;
            }
            private set
            {
                this._path = value;
            }
        }

        [Browsable(false)]
        public RasPhoneBookType PhoneBookType
        {
            get
            {
                return this._phoneBookType;
            }
            private set
            {
                this._phoneBookType = value;
            }
        }
    }
}

